home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / c / cp1.zip / HUGEREAD.C < prev    next >
C/C++ Source or Header  |  1993-05-26  |  4KB  |  156 lines

  1. ===========================================================================
  2.  BBS: The Abacus * HST/DS * Potterville MI
  3. Date: 05-23-93 (19:12)             Number: 63
  4. From: BOB STOUT                    Refer#: 36
  5.   To: BOB WITHERS                   Recvd: NO  
  6. Subj: Pascal'S Move = C'S ?          Conf: (36) C Language
  7. ---------------------------------------------------------------------------
  8. In a message of <May 22 09:19>, Bob Withers (1:124/1007@fidonet) writes:
  9.  
  10.  >Note that some DOS compilers may not allow reads of blocks this big in
  11.  >a single call.
  12.  
  13.   *Most* DOS compilers won't! Here's a solution from SNIPPETS:
  14.  
  15. /*
  16. **  HUGEREAD.C - "Universal" PC read and write functions using huge data
  17. **               and far pointers.
  18. **
  19. **  NOTES:
  20. **
  21. **  1. If these functions are called with a prototype in scope, passed
  22. **     parameters will be coerced to the proper data types.
  23. **
  24. **  2. Since these call read() and write(), all normal mode flags which
  25. **     are supported by individual compilers will be honored.
  26. **
  27. **  3. In small data memory models (S, T, and M), an intermediate buffer
  28. **     is allocated and used. In large data models (L and C), the data
  29. **     are read/written directly from/to target memory.
  30. **
  31. **  4. Like many mixed-model functions, this may generate lots of warnings
  32. **     with many compilers. Despite this, it really does generate correct
  33. **     code for all major PC compilers.
  34. **
  35. **  Original Copyright 1992 by Bob Stout as part of
  36. **  the MicroFirm Function Library (MFL)
  37. **
  38. **  This subset version is hereby donated to the public domain.
  39. */
  40.  
  41. #include <dos.h>
  42. #include <io.h>
  43. #include <stdlib.h>
  44. #include <stddef.h>
  45.  
  46. #ifdef __TURBOC__
  47.  #define FAR far
  48. #else
  49.  #define FAR _far
  50. #endif
  51.  
  52. #ifndef min
  53.  #define min(x,y) (((x) <= (y)) ? (x) : (y))
  54. #endif
  55.  
  56. #ifndef MK_FP
  57.  #define MK_FP(seg,offset) \
  58.         ((void FAR *)(((unsigned long)(seg)<<16) | (unsigned)(offset)))
  59. #endif
  60.  
  61. /*
  62. **  Get the largest buffer possible.
  63. */
  64.  
  65. static size_t gettmp(char **buf)
  66. {
  67.       size_t bufsiz;
  68.  
  69.       for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1)
  70.       {
  71.             if (NULL != (*buf = (char *) malloc(bufsiz)))
  72.                   return bufsiz;
  73.       }
  74.       return 0;
  75. }
  76.  
  77. /*
  78. **  Normalize a far pointer
  79. */
  80.  
  81. void FAR *farnormal(void FAR *ptr)
  82. {
  83.       size_t seg, ofs;
  84.  
  85.       seg = FP_SEG(ptr);
  86.       ofs = FP_OFF(ptr);
  87.       return MK_FP(seg + (ofs >> 4), ofs & 0xf);
  88. }
  89.  
  90. /*
  91. **  Read any size block to anywhere in memory
  92. */
  93.  
  94. long hugeread(int fh, char FAR *buf, long size)
  95. {
  96.       long count;
  97.       size_t bufsiz;
  98.       char *tmp;
  99.       long ercode = size;
  100.  
  101.       if (4 > sizeof(void *))
  102.       {
  103.             if (0 == (bufsiz = gettmp(&tmp)))
  104.                   return -1L;
  105.       }
  106.       else
  107.       {
  108.             tmp = (char *)buf;
  109.             bufsiz = 0x4000;
  110.       }
  111.  
  112.       while (0 < (count = min(size, (long)bufsiz)))
  113.       {
  114.             int i, numread = read(fh, tmp, (size_t)count);
  115.  
  116.             if (1 > numread || numread != (int)count)
  117.                   return -1L;
  118.             if (4 > sizeof(void *))
  119.             {
  120.                   for (i = 0; i < count; ++i)
  121.                         buf[i] = tmp[i];
  122.             }
  123.             buf = farnormal(buf + count);
  124.             size -= count;
  125.             if (2 < sizeof(void *))
  126.                   tmp = (char *)buf;
  127.       }
  128.       return ercode;
  129. }
  130.  
  131. /*
  132. **  Write any size block from anywhere in memory
  133. */
  134.  
  135. long hugewrite(int fh, char FAR *buf, long size)
  136. {
  137.       long count;
  138.       size_t bufsiz;
  139.       char *tmp;
  140.       long ercode = size;
  141.  
  142.       if (4 > sizeof(void *))
  143.       {
  144.             if (0 == (bufsiz = gettmp(&tmp)))
  145.                   return -1L;
  146.       }
  147.       else
  148.       {
  149.             tmp = (char *)buf;
  150.             bufsiz = 0x4000;
  151.       }
  152.  
  153.       while (0 < (count = min(size, (long)bufsiz)))
  154.       {
  155.             int i, numwrite;
  156.